﻿using System.CodeDom.Compiler;
using System.Text;

namespace ShadowCode.Injection.Base;
public abstract class GeneratorBase : ShadowCode.GeneratorBase
{
    internal static string project_dir = "_project_dir";
    internal string use_method_name = "_use_method_name";
    internal string root_namespace = "_root_namespace";
    internal string class_name = "ShadowCodeInjectionExtensions";


    protected const string parameter = "IServiceCollection service, IConfigurationManager? config = null";
    protected const string userusage = "预留用户扩展入口";
    protected const string generator = "生成器调用(请勿使用)";
    protected const string userusageSummary = $"/// <summary> {userusage} </summary>";
    protected const string generatorSummary = $"/// <summary> {generator} </summary>";

    protected static string GetName(NameSyntax nameSyntax) => nameSyntax switch
    {
        IdentifierNameSyntax iName => iName.Identifier.ValueText,
        GenericNameSyntax gName => gName.Identifier.ValueText,
        _ => string.Empty,
    };

    protected virtual TransformData Transform(GeneratorSyntaxContext context,
        CancellationToken token)
    {
        return new(context);
    }

    protected override void AnalyzerConfigHandler(AnalyzerConfigOptionsProvider options)
    {
        var map = options.GlobalOptions;

        if (map.TryGetValue("build_property.projectdir", out var dir))
            project_dir = dir;

        if (map.TryGetValue("build_property.rootnamespace", out var rootnamespace) &&
            rootnamespace.Trim() is { Length: > 0 })
            root_namespace = rootnamespace;

        use_method_name = $"Use{root_namespace.Replace('.', '_')}";

        const string use_name_prop = "build_property.shadowcode_injection_usemethodname";
        if (map.TryGetValue(use_name_prop, out var useName) &&
            useName.Trim() is { Length: > 0 })
            use_method_name = useName.Trim().Replace(' ', '_').Replace('.', '_');
    }

    internal void WriteClassStart(IndentedTextWriter textWriter)
    {
        textWriter.WriteLine($$"""
        #pragma warning disable
        using Microsoft.Extensions.Configuration;
        using Microsoft.Extensions.DependencyInjection;
        using Microsoft.Extensions.DependencyInjection.Extensions;
        using Microsoft.Extensions.Options;

        namespace {{root_namespace}};
        public static partial class {{class_name}}
        """);
    }

    internal StringBuilder Writer(Action<IndentedTextWriter> action)
    {
        var sb = new StringBuilder();
        using var sw = new StringWriter(sb);
        using var tw = new IndentedTextWriter(sw);
        action(tw);
        return sb;
    }
}